#pragma once
#ifndef SHADER_HPP
#define SHADER_HPP
#include "glad/glad.h"
#include <string>
#include <iostream>
#include <glm/glm.hpp>

class Shader {
public:
    uint32_t ID;
    Shader() { ID = 0; };
    Shader(std::string vertPath, std::string fragmPath);

    inline void setBool(std::string name, bool value) const
    {
        glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
    }
    inline void setInt(std::string name, int value) const
    {
        glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
    }
    inline void setFloat(std::string name, float value) const
    {
        glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
    }

    inline void setMat3(std::string name, glm::mat3& value) const
    {
        glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &value[0][0]);
    }
    inline void setMat4(std::string name, glm::mat4& value) const
    {
        glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &value[0][0]);
    }
    inline void setMat4(std::string name, const glm::mat4* value) const
    {
        glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &value->operator[](0)[0]);
    }

    inline void setVec3(std::string name, const float value[3]) const
    {
        glUniform3f(glGetUniformLocation(this->ID, name.c_str()), value[0], value[1], value[2]);
    }
    inline void setVec3(std::string name, const glm::vec3 value) const
    {
        glUniform3f(glGetUniformLocation(this->ID, name.c_str()), value.x, value.y, value.z);
    }

    inline void use() const
    {
        glUseProgram(ID);
    }
    inline void del()
    {
        glDeleteProgram(ID);
    }

private:
    void checkCompileErrors(uint32_t shader, std::string type);
};
#endif // SHADER_HPP
